#include "aio.h"
extern "C" {
#include <errno.h>
#include <string.h>
}
#include <memory>
#include <iostream>
#include "socket.h"

using namespace std;


bool async_io::_write::_write_return::await_ready() const {
    int ret = wr->sock->send(wr->ptr, wr->size, wr->flag);
    if(ret == -1) {
        if(errno != EAGAIN)
            throw std::runtime_error(
                    std::string("tcp_connection::_write::await_ready sock.send() error: ") + strerror(errno));
        wr->_waiting = true;
        return false;
    }else {
        wr->result = ret;
        return true;
    }
}

int async_io::_write::_write_return::await_resume() const {
    int ret;
    if(wr->result == -1) {
        ret = wr->sock->send(wr->ptr, wr->size, wr->flag);
        wr->_waiting = false;
    }else
        ret = wr->result;
    return ret;
}

bool async_io::_read::_read_return::await_ready() const {
    int ret = rd->sock->recv(rd->ptr, rd->size, rd->flag);
    if(ret == -1) {
        if(errno != EAGAIN)
            throw std::runtime_error(
                    std::string("tcp_connection::_write::await_ready sock.recv() error: ") + strerror(errno));
        rd->_waiting = true;
        return false;
    }else {
        rd->result = ret;
        return true;
    }
}

int async_io::_read::_read_return::await_resume() const {
    int ret;
    if(rd->result == -1) {
        ret = rd->sock->recv(rd->ptr, rd->size, rd->flag);
        if(ret == -1)
            throw std::runtime_error(
                    std::string("tcp_connection::_write::await_resume() ") + \
                    std::to_string(rd->sock->fileno()) +
                    " should not return -1, error: " + strerror(errno));
        rd->_waiting = false;
    }else
        ret = rd->result;
    return ret;
}
